// UEServiceWorker.h
#ifndef UE_SERVICE_WORKER_H
#define UE_SERVICE_WORKER_H

#include "libue.h"
class CUEService;

#define UE_WORKER_ROLE_GUEST      0                       // unauthenticated
#define UE_WORKER_ROLE_ADMIN      0                       // authenticated rull control role

class CUEServiceWorker 
{
public:
	CUEServiceWorker(CUEService *pUEService, int c, int from_addr, int from_port);
	~CUEServiceWorker();

public:
	/* Work thread to handle each incoming connection.
	 * @param[in] lpParam Pointer to one instance of CUEServiceWorker for the incoming connection.
	 * @return 0 indicate success, otherwise some error occur.
	 */
	static DWORD WINAPI WorkingThread(LPVOID lpParam);

	/* Retrieving the Class Identifier for an Encoder for GDI+.
	 * @param[in] format The MIME type of an encoder. Can be one of image/bmp, image/jpeg, image/gif, image/tiff or image/png.
	 * @param[out] pClsid The retrieved class identifier.
	 * @return 0 indicate success, otherwise some error occur.
	 */
	static BOOL GetEncoderClsid(const WCHAR* format, CLSID* pClsid);

	/* Class Identifier of the encoder for GDI+ for the output image */
	static CLSID s_imgClsid;

protected:
	/* Read the whole UE request header from socket.
	 * @param[out] pRequestHeader Pointer to the ue_request_header struct to store the request header read from socket.
	 * @return TRUE indicate success, otherwise some error occur.
	 */
	BOOL   ReadRequestHeader(ue_request_header* pRequestHeader);

	/* Handle the request defined in request_header.
	 * @param[in] pRequestHeader Pointer to the ue_request_header struct which store the request header.
	 * @return TRUE indicate success, otherwise some error occur.
	 */
	BOOL   RequestHandler(const ue_request_header* pRequestHeader);

	/* Handle the stop service request.
	 * @param[in] pRequestHeader Pointer to the ue_request_header struct which store the request header.
	 * @return TRUE indicate success, otherwise some error occur.
	 */
	BOOL   HandleStopRequest(const ue_request_header* pRequestHeader);

	/* Handle the authentication request.
	 * @param[in] pRequestHeader Pointer to the ue_request_header struct which store the request header.
	 * @return TRUE indicate success, otherwise some error occur.
	 */
	BOOL   HandleAuthRequest(const ue_request_header* pRequestHeader);

	/* Handle the action request.
	 * @param[in] pRequestHeader Pointer to the ue_request_header struct which store the request header.
	 * @return TRUE indicate success, otherwise some error occur.
	 */
	BOOL   HandleActionRequest(const ue_request_header* pRequestHeader);

	/* Handle the update request.
	 * @param[in] pRequestHeader Pointer to the ue_request_header struct which store the request header.
	 * @return TRUE indicate success, otherwise some error occur.
	 */
	BOOL   HandleUpdateRequest(const ue_request_header* pRequestHeader);

	/* Send the whole UE request header from socket.
	 * @param[in] pResponseHeader Pointer to the ue_response_header struct to store the response header.
	 * @return TRUE indicate success, otherwise some error occur.
	 */
	BOOL   SendResponseHeader(const ue_response_header* pResponseHeader);

	/* Get the current screen capture image to buffer.
	 * @param[out] pbuf Pointer to the buf to store the image data. After finish use it, call free() to release the buf.
	 * @param[out] pScreenWidth Pointer to store the screen width.
	 * @param[out] pScreenHeight Pointer to store the screen height.
	 * @return 0 indicate error occur, otherwise return the size of the image data.
	 */
	int   GetFullScreen(char** pbuf, int *pScreenWidth, int *pScreenHeight);

public:
	int                m_FromAddr;                        // address of the client
	unsigned short     m_FromPort;                        // port of the client

protected:
	CUEService        *m_pUEService;                      // pointer to CUEService instance
	int                m_ClientSocket;                    // client socket file descriptor
	int                m_nRole;                           // Authenticated role for this worker
};

#endif // UE_SERVICE_WORKER_H
